Ruby 日記 6日目: refineとusing
次のコードを実行するとどうなりますか
code:gold/ex06/main.rb
class C
end
module M
refine C do
def m1
100
end
end
end
class C
def m1
400
end
def self.using_m
using M
end
end
C.using_m
puts C.new.m1
選択肢:
100と表示される
200と表示される
300と表示される
エラーが発生する
引数 klass で指定したクラスだけに対して、ブロックで指定した機能を提供で きるモジュールを定義します。定義した機能は Module#refine を使用せずに直 接 klass に対して変更を行う場合と異なり、限られた範囲のみ有効にできます。 そのため、既存の機能を局所的に修正したい場合などに用いる事ができます。
ふむふむ〜。普段なかなか使わないやつだ。
定義した機能は main.using, Module#using を実行した場合のみ 有効になります。
ほ〜。
usingについては
引数で指定したモジュールで定義された拡張を現在のクラス、モジュールで有 効にします。
引数で指定したモジュールで定義された拡張を有効にします。
具体例がないなぁ
code:using_sample.rb
module Sloth
refine String do
def downcase
self
end
end
end
"ABC".downcase # => "abc"
using Sloth
"ABC".downcase # => "ABC"
なるほど
If using is called in a class/module definition or a method definition, raise a RuntimeError.
クラス/モジュール定義またはメソッド定義でusingが呼び出された場合は、RuntimeErrorを発生させます、とのこと
code:sh
# ruby gold/ex06/main.rb
gold/ex06/main.rb:18:in `using': Module#using is not permitted in methods (RuntimeError)
from gold/ex06/main.rb:18:in `using_m'
from gold/ex06/main.rb:22:in `<main>'
答えは「エラーが発生する」だね
/icons/hr.icon
たとえば
code:gold/ex06/sample1.rb
class C
end
module M
refine C do
def m1
100
end
end
end
class C
def m1
400
end
end
c = C.new
puts c.m1
using M
puts c.m1
code:sh
# ruby gold/ex06/sample1.rb
400
100
へ〜
/icons/hr.icon
さらに〜〜?
code:gold/ex06/sample2.rb
class C
end
module M
refine C do
def m1
100
end
end
end
class C
def m1
400
end
using M
def m2
m1
end
end
c = C.new
puts c.m1
puts c.m2
code:sh
# ruby gold/ex06/sample2.rb
400
100
なるほど〜!